#import "FlutterPushPlugin.h"
#import <UserNotifications/UserNotifications.h>
#import <CloudPushSDK/CloudPushSDK.h>

@interface FlutterPushPlugin()<UIApplicationDelegate>

@property (nonatomic, strong)FlutterMethodChannel* channel;

@end

@implementation FlutterPushPlugin

static FlutterPushPlugin * formatMediaManager = nil;

+ (FlutterPushPlugin *)sharedChatboardPluginlManagerRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
{
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^(){
        formatMediaManager = [[FlutterPushPlugin alloc] initRegistrar:registrar];
    });
    return formatMediaManager;
}

-(instancetype)initRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
{
    self = [super init];
    if(self)
    {
        [registrar addApplicationDelegate:self];
    }
    return self;
}

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions
{
    NSLog(@"初始化 推送");
    
    [application setApplicationIconBadgeNumber:0];
    
    [self registerAPNS:application];
    
    [CloudPushSDK asyncInit:@"31080025" appSecret:@"c91aff349c25545227e544d98bc0528f" callback:^(CloudPushCallbackResult *res) {
        if (res.success)
        {
            NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]);
            
            [CloudPushSDK syncBadgeNum:0 withCallback:^(CloudPushCallbackResult *res) {
                
            }];
        }
        else
        {
            NSLog(@"Push SDK init failed, error: %@", res.error);
        }
    }];
    
    NSLog(@"version    %@",[CloudPushSDK getVersion]);
    
    [self registerMessageReceive];
    
    return YES;
}

/**
 *    注册苹果推送，获取deviceToken用于推送
 *
 *    @param     application
 */
- (void)registerAPNS:(UIApplication *)application
{
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            // granted
            NSLog(@"User authored notification.");
            dispatch_async(dispatch_get_main_queue(), ^{
                [application registerForRemoteNotifications];
            });
        } else {
            // not granted
            NSLog(@"User denied notification.");
        }
    }];
}

/*
 *  苹果推送注册成功回调，将苹果返回的deviceToken上传到CloudPush服务器
 */
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
    
    NSLog(@"deviceToken   deviceToken   deviceToken");
    
    if (![deviceToken isKindOfClass:[NSData class]]) {
               //记录获取token失败的描述
               return;
    }
    const unsigned *tokenBytes = (const unsigned *)[deviceToken bytes];
    NSString *strToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                         ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                         ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                         ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
    
    NSLog(@"deviceToken1:%@", strToken);
    
    NSLog(@"Upload deviceToken to CloudPush server.");
    
    [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) {
        if (res.success) {
            NSLog(@"Register deviceToken success, deviceToken: %@", [CloudPushSDK getApnsDeviceToken]);
        } else {
            NSLog(@"Register deviceToken failed, error: %@", res.error);
        }
    }];
}

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"推送  error   %@",error);
}
/**
 *    注册推送消息到来监听
 */
- (void)registerMessageReceive {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onMessageReceived:)
                                                 name:@"CCPDidReceiveMessageNotification"
                                               object:nil];
}
/**
 *    处理到来推送消息
 *
 *    @param     notification
 */
- (void)onMessageReceived:(NSNotification *)notification {
    CCPSysMessage *message = [notification object];
    NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding];
    NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding];
    
    [_channel invokeMethod:@"receiveMessage" arguments:@{@"id":@"1",@"title":title,@"content":body}];
}

/**
 *  处理iOS 10通知(iOS 10+)
 */
- (void)handleiOS10Notification:(UNNotification *)notification {
    UNNotificationRequest *request = notification.request;
    UNNotificationContent *content = request.content;
    NSDictionary *userInfo = content.userInfo;
    
    NSString *extras = [userInfo valueForKey:@"Extras"];
    
    [_channel invokeMethod:@"receiveNotification" arguments:extras];
    
    // 通知打开回执上报
    [CloudPushSDK sendNotificationAck:userInfo];
    NSLog(@"Notification%@", userInfo);
}

/**
 *  App处于前台时收到通知(iOS 10+)
 */
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSLog(@"Receive a notification in foregound.");
    // 处理iOS 10通知相关字段信息
    [self handleiOS10Notification:notification];
    // 通知不弹出
    //completionHandler(UNNotificationPresentationOptionNone);
    // 通知弹出，且带有声音、内容和角标（App处于前台时不建议弹出通知）
    completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}

/**
 *  触发通知动作时回调，比如点击、删除通知和点击自定义action(iOS 10+)
 */
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
    NSString *userAction = response.actionIdentifier;
    // 点击通知打开
    if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
        NSLog(@"User opened the notification.");
        // 处理iOS 10通知，并上报通知打开回执
        [self handleiOS10Notification:response.notification];
        
        UNNotificationRequest *request = response.notification.request;
        UNNotificationContent *content = request.content;
        NSDictionary *userInfo = content.userInfo;
        
        // 取得通知自定义字段内容，例：获取key为"Extras"的内容
        NSString *extras = [userInfo valueForKey:@"Extras"];
        
        [_channel invokeMethod:@"openNotification" arguments:extras];
    }
    // 通知dismiss，category创建时传入UNNotificationCategoryOptionCustomDismissAction才可以触发
    if ([userAction isEqualToString:UNNotificationDismissActionIdentifier]) {
        NSLog(@"User dismissed the notification.");
    }
    NSString *customAction1 = @"action1";
    NSString *customAction2 = @"action2";
    // 点击用户自定义Action1
    if ([userAction isEqualToString:customAction1]) {
        NSLog(@"User custom action1.");
    }
    // 点击用户自定义Action2
    if ([userAction isEqualToString:customAction2]) {
        NSLog(@"User custom action2.");
    }
    completionHandler();
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                     methodChannelWithName:@"flutter_push"
                                     binaryMessenger:[registrar messenger]];
    
    FlutterPushPlugin* instance = [FlutterPushPlugin sharedChatboardPluginlManagerRegistrar:registrar];
    instance.channel = channel;
    [registrar addMethodCallDelegate:instance channel:channel];
}

-(void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
{
    //NSLog(@"推送   %@    param    %@",call.method,call.arguments);
    
    if([call.method isEqualToString:@"registerPushService"])
    {
        [CloudPushSDK bindAccount:call.arguments[@"accountId"] withCallback:^(CloudPushCallbackResult *res) {
            NSLog(@"res绑定accountID 是否成功     %d",res.success);
        }];
        result(nil);
        return;
    }
    
    if([call.method isEqualToString:@"unregisterPushService"])
    {
        [CloudPushSDK unbindAccount:^(CloudPushCallbackResult *res) {
            
            NSLog(@"res     %@",res);
        }];
        result(nil);
        return;
    }
    
    if ([@"getPlatformVersion" isEqualToString:call.method]) {
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
        return;
    }
    result(FlutterMethodNotImplemented);
}

@end
